Write a custom CUDA kernel to optimize `RankNet Loss`.

Formula: L = Sum_{i,j where y_i > y_j} log(1 + exp(-(s_i - s_j)))
Where `s` are predicted scores and `y` are ground truth labels.

Problem Analysis:
1. Quadratic Complexity: The loss requires comparing every pair of items in the list. For a list size N, there are N^2 pairs.
2. Memory Explosion: A standard PyTorch implementation uses broadcasting (`s[:, :, None] - s[:, None, :]`) to construct an (N, N) difference matrix. For batched inputs, this creates a (Batch, N, N) intermediate tensor, which creates enormous memory pressure and write bandwidth usage for what is essentially a scalar reduction.

Optimization Strategy: Fused Pairwise Reduction in Shared Memory

1. Block-per-Query: Assign one CUDA block to process one list (query).

2. Shared Memory Caching:
   - Load the input `scores` and `labels` vectors (length N) into Shared Memory.
   - This reduces global memory reads from O(N^2) to O(N).

3. Tiled/Strided Pairwise Iteration:
   - The threads in the block collaboratively iterate over the N^2 possible pairs indices (0 to N*N-1).
   - Each thread calculates `i = idx / N` and `j = idx % N`.
   - It reads `labels[i]`, `labels[j]`, `scores[i]`, `scores[j]` from Shared Memory (fast random access).
   - Condition check: If `labels[i] > labels[j]`, compute `loss += log(1 + exp(-(s_i - s_j)))`.

4. Block Reduction:
   - Sum the local partial losses from all threads.
   - Write the final scalar loss for the query to global memory.

This approach reduces memory complexity from O(N^2) to O(N) and fuses the quadratic computation into high-speed on-chip operations.
  
Here's an example to show you the syntax of inline embedding custom CUDA operators in torch: The example given architecture is:   
  
```python
import torch
import torch.nn as nn
import torch.nn.functional as F

BATCH_SIZE = 128
LIST_SIZE = 1024
SHAPE = (BATCH_SIZE, LIST_SIZE)

REDUCTION = 'none'

class RankNetLoss(nn.Module):
    """
    RankNet Loss (pairwise)
    L = sum_{i,j: y_i > y_j} log(1 + exp(-(s_i - s_j)))
    """
    def __init__(self, reduction='mean'):
        super(RankNetLoss, self).__init__()
        self.reduction = reduction

    def forward(self, scores: torch.Tensor, labels: torch.Tensor) -> torch.Tensor:
        # scores: (B, N)
        # labels: (B, N)

        s_diff = scores.unsqueeze(2) - scores.unsqueeze(1)

        y_diff = labels.unsqueeze(2) - labels.unsqueeze(1)

        mask = (y_diff > 0).float()

        loss_matrix = F.softplus(-s_diff)

        masked_loss = loss_matrix * mask
        
        sample_loss = masked_loss.sum(dim=(1, 2))
        
        if self.reduction == 'mean':
            return sample_loss.mean()
        elif self.reduction == 'sum':
            return sample_loss.sum()
        return sample_loss

class Model(nn.Module):
    def __init__(self, reduction='none'):
        super(Model, self).__init__()
        self.loss_fn = RankNetLoss(reduction=reduction)
    
    def forward(self, scores, labels):
        return self.loss_fn(scores, labels)

def get_inputs():
    scores = torch.randn(SHAPE, dtype=torch.float32)
    labels = torch.randint(0, 5, SHAPE, dtype=torch.float32)
    return [scores.contiguous(), labels.contiguous()]

def get_init_inputs():
    return [REDUCTION]